package com.litbw.user;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.LayoutStyle;
import javax.swing.event.MouseInputAdapter;

import com.litbw.gui.AbstractObservablePanel;

/**
 * 
 * @author dirk
 * @edited Trygve Stageberg
 */
@SuppressWarnings("serial")
public class DraftMakerPanel extends AbstractObservablePanel {
	private Color backgroundColor = Color.GRAY;
	private Color ColorChooserbackground = Color.DARK_GRAY;
	private Color DraftbackgroundColor = Color.WHITE;
	private JPanel drawDown;
	private JPanel horizontle_color;
	private JPanel horizontle_pick;
	private JPanel treadle;
	private JPanel verticle_color;
	private JPanel warp;

	private static int TREADLE_SIZE = 8;
	private int PIXELS = 16;

	private boolean[][] treadle2d;
	private boolean[][] warp2d;
	private boolean[][] horizontal2d;
	private Color[][] horizontalColorChooser;
	private Color[][] warpColorChooser;
	private JLabel[][] drawDown2d;
	public DraftMakerPanel() {
		setPreferredSize(new Dimension(800, 800));
		treadle = new JPanel();
		treadle.setName("t");
		warp = new JPanel();
		warp.setName("v");
		horizontle_pick = new JPanel();
		horizontle_pick.setName("h");
		verticle_color = new JPanel();
		horizontle_color = new JPanel();
		drawDown = new JPanel();

		treadle.setPreferredSize(new Dimension(TREADLE_SIZE * PIXELS,
				TREADLE_SIZE * PIXELS));

		warp.setPreferredSize(new Dimension(TREADLE_SIZE * PIXELS,
				getPreferredSize().height - (TREADLE_SIZE * PIXELS)));
		horizontle_pick.setPreferredSize(new Dimension(getPreferredSize().width
				- (TREADLE_SIZE * PIXELS), TREADLE_SIZE * PIXELS));

		drawDown.setPreferredSize(new Dimension(getPreferredSize().width
				- (TREADLE_SIZE * PIXELS), getPreferredSize().height
				- (TREADLE_SIZE * PIXELS)));

		treadle2d = new boolean[TREADLE_SIZE][TREADLE_SIZE];

		warp2d = new boolean[warp.getPreferredSize().height
				/ PIXELS][TREADLE_SIZE];
		warpColorChooser = new Color[warp.getPreferredSize().height
				/ PIXELS][1];
		
		
		

		horizontal2d = new boolean[TREADLE_SIZE][horizontle_pick
				.getPreferredSize().width / PIXELS];
		horizontalColorChooser = new Color[1][horizontle_pick
				.getPreferredSize().width / PIXELS];

		drawDown2d = new JLabel[horizontal2d[0].length][warp2d.length];
		//warp2d[3][1] = true;
		//horizontal2d[0][3] = true;
		initComponents();
		
	}

	private void initComponents() {

		treadle.setLayout(new GridLayout(TREADLE_SIZE, TREADLE_SIZE));
		loadComponent(treadle, treadle2d);

		warp.setLayout(new GridLayout(warp2d.length,
				warp2d[0].length));
		loadComponent(warp, warp2d);
		
		horizontle_pick.setLayout(new GridLayout(horizontal2d.length,
				horizontal2d[0].length));
		loadComponent(horizontle_pick, horizontal2d);

		drawDown.setLayout(new GridLayout(warp2d.length,
				horizontal2d[0].length));
		loadDrawDownComponent();

		verticle_color.setBorder(BorderFactory
				.createLineBorder(new Color(0, 0, 0)));
		verticle_color.setPreferredSize(new Dimension(PIXELS , PIXELS * 4));
		verticle_color.setLayout(new GridLayout(warp2d.length, 1));
		verticle_color.setName("vcc");
		loadColorComponent(verticle_color, warpColorChooser);

		
		horizontle_color.setPreferredSize(new Dimension(PIXELS * 4, PIXELS));
		horizontle_color.setLayout(new GridLayout(1, horizontal2d[0].length));
		loadColorComponent(horizontle_color, horizontalColorChooser);
		
        GroupLayout layout = new GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(horizontle_color, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(horizontle_pick, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE)
                    .addComponent(drawDown, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(warp, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(verticle_color, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addComponent(treadle, GroupLayout.PREFERRED_SIZE, TREADLE_SIZE * PIXELS, GroupLayout.PREFERRED_SIZE)))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(warp, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 287, Short.MAX_VALUE)
                    .addComponent(verticle_color, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(drawDown, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                    .addComponent(treadle, GroupLayout.PREFERRED_SIZE, TREADLE_SIZE * PIXELS, GroupLayout.PREFERRED_SIZE)
                    .addComponent(horizontle_pick, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(horizontle_color, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
        );
	}


	private void loadDrawDownComponent() {
		for(int y= 0; y < drawDown2d.length; y++){
			JLabel[] labels = drawDown2d[y];
			for(int x = 0; x < drawDown2d[0].length; x++){
				labels[x] = new JLabel();
				labels[x].setOpaque(true);
				labels[x].setBorder(BorderFactory.createLineBorder(Color.BLACK));
				labels[x].setBackground(DraftbackgroundColor);
				drawDown.add(labels[x]);
			}
		}
	}

	private void loadColorComponent(JPanel component,
			Color[][] bool_2d) {
		for (int y = 0; y < bool_2d.length; y++) {
			Color[] bool = bool_2d[y];
			for (int x = 0; x < bool_2d[0].length; x++) {
				Color b = bool[x];
				
				
				
				final JLabel label = new JLabel();
				label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
				if (b == null)
					b = ColorChooserbackground;
				horizontalColorChooser[0][x] = b;
				warpColorChooser[y][0] = b;

				
				label.setBackground(b);
				label.setOpaque(true);
				label.addMouseListener(new MouseInputAdapter() {
					Color curr = label.getBackground();
					@Override
					public void mouseClicked(MouseEvent e) {
						Component comp = e.getComponent();
						String name = comp.getParent().getName();
						int col = (comp.getX() - 1) / (PIXELS - 1);
						int row = (comp.getY() - 1) / (PIXELS - 1);
						 Color bgColor
					      = JColorChooser.showDialog(null,
					                                 "Choose Background Color",
					                                 getBackground());
						 if (bgColor != null){
							 label.setBackground(bgColor);
							 curr = bgColor;
							 if(name == "vcc")
								 warpColorChooser[row][0] = bgColor;
							 else {
								 horizontalColorChooser[0][col] = bgColor;
							 }
						 } 
					}

					@Override
					public void mouseDragged(MouseEvent e){
						Component comp = e.getComponent();
						String name = comp.getParent().getName();
						int x = (comp.getX() - 1) / (PIXELS - 1);
						int y = (comp.getY() - 1) / (PIXELS - 1);
						 Color bgColor
					      = JColorChooser.showDialog(null,
					                                 "Choose Background Color",
					                                 getBackground());
						 if (bgColor != null){
							 label.setBackground(bgColor);
							 curr = bgColor;
						 }
					}
					
					
					@Override
					public void mouseEntered(MouseEvent e) {
						label.setBackground(Color.YELLOW);
					}

					@Override
					public void mouseExited(MouseEvent e) {
						label.setBackground(curr);
					}
				});

				component.add(label);


			}
		}
	}
	private void loadComponent(JPanel component, boolean[][] bool_2d) {
		for (int y = 0; y < bool_2d.length; y++) {
			boolean[] bool = bool_2d[y];
			for (int x = 0; x < bool_2d[0].length; x++) {
				boolean b = bool[x];
				final JLabel label = new JLabel();
				label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
				if (b == false)
					label.setBackground(backgroundColor);
				else
					label.setBackground(Color.BLACK);
				label.setOpaque(true);
				label.addMouseListener(new MouseInputAdapter() {
					Color curr = label.getBackground();
					@Override
					public void mouseClicked(MouseEvent e) {
						Component comp = e.getComponent();
						String name = comp.getParent().getName();
						int x = (comp.getX() - 1) / (PIXELS - 1);
						int y = (comp.getY() - 1) / (PIXELS - 1);
						
							if (curr == Color.BLACK) {
								label.setBackground(backgroundColor);
								curr = backgroundColor;
								if(name == "v"){
									warp2d[y][x] = false;
									removeWarpThread(y);
								} else if (name == "h"){
									horizontal2d[y][x] = false;
									removeWeftThread(x);
								} else {
									treadle2d[y][x] = false;
									for(int i = 0; i < horizontal2d[0].length; i++){
										boolean b = horizontal2d[y][i];
										if(b == true){
											shootWeftThread(i, y);
										}
									}
									for(int i = 0; i < warp2d.length; i++){
										boolean b = warp2d[i][x];
										if(b == true){
											shootWarpThread(i, x);
										}
									}
								}
							} else {
								label.setBackground(Color.BLACK);
								curr = Color.BLACK;
								if(name == "v"){
									warp2d[y][x] = true;
									shootWarpThread(y, x);
								} else if (name == "h"){
									horizontal2d[y][x] = true;
									shootWeftThread(x, y);
								} else {
									treadle2d[y][x] = true;		
									for(int i = 0; i < horizontal2d[0].length; i++){
										boolean b = horizontal2d[y][i];
										if(b == true){
											shootWeftThread(i, y);
										}
									}
									for(int i = 0; i < warp2d.length; i++){
										boolean b = warp2d[i][x];
										if(b == true){
											shootWarpThread(i, x);
										}
									}
																	
								}
							}							

					}

					@Override
					public void mouseEntered(MouseEvent e) {
						label.setBackground(Color.YELLOW);
					}

					@Override
					public void mouseExited(MouseEvent e) {
						label.setBackground(curr);
					}
				});

				component.add(label);


			}
		}
	}

	private int isWeftSelected(int colNum){
		for(int i = 0; i < TREADLE_SIZE; i++){
			if(horizontal2d[i][colNum] == true)
				return i;
		}
		return -1;
	}
	
	private int isWarpSelected(int rowNum){
		for(int i = 0; i < TREADLE_SIZE; i++){
			if(warp2d[rowNum][i] == true)
				return i;
		}
		return -1;
	}
	
	private void shootWarpThread(int the_end, int treadle_number) {
		for (int i = 0; i < horizontal2d[0].length; i++) {
			int selection = isWeftSelected(i);
			if (selection != -1) {
				if (treadle2d[selection][treadle_number]) {
					drawDown2d[the_end][i]
							.setBackground(warpColorChooser[the_end][0]);
				} else {
					drawDown2d[the_end][i]
							.setBackground(horizontalColorChooser[0][i]);
				}
			}
		}
	}
	
	/*
	 * verticle
	 */
	private void shootWeftThread(int the_pick, int treadle_number){
		for(int i = 0; i < warp2d.length; i++){
			int selection = isWarpSelected(i);
			if(selection != -1){
				if(treadle2d[selection][treadle_number])	
					drawDown2d[i][the_pick].setBackground(warpColorChooser[i][0]);
				else
					drawDown2d[i][the_pick].setBackground(horizontalColorChooser[0][the_pick]);

			}
		}
	}
	
	/*
	 * horizontal
	 */
	private void removeWarpThread(int the_end) {
		boolean doNothing = false;
		for(int i = 0; i < TREADLE_SIZE; i++){
			if(warp2d[the_end][i] == true)
				doNothing = true;
		}
		if(!doNothing)
		for (int i = 0; i < horizontal2d[0].length; i++) {
				drawDown2d[the_end][i].setBackground(backgroundColor);
		}
	}
	
	/*
	 * verticle
	 */
	private void removeWeftThread(int the_pick) {
		boolean doNothing = false;
		for(int i = 0; i < TREADLE_SIZE; i++){
			if(horizontal2d[i][the_pick] == true)
				doNothing = true;
		}
		if(!doNothing)
		for(int i = 0; i < warp2d.length; i++){
			
			drawDown2d[i][the_pick].setBackground(backgroundColor);
		}
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		DraftMakerPanel draft = new DraftMakerPanel();
		
		frame.add(draft);
		frame.pack();
		frame.setVisible(true);
	}

}
